/***********************************************************************************
**  
* @copyright (c) 2010-2019, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
************************************************************************************/
/**
* @file	    mjs_client_proxy.cpp
* @version     
* @brief      
* @author   duye
* @date	    2016-12-22
* @note 
*
* 1. 2016-12-22 duye Created this file
*/

#include <duye_type.h>
#include <duye_xml.h>
#include <duye_buffer.h>
#include <duye_logger.h>
#include <duye_cfg_mgr.h>
#include <mj_net_protocol.h>
#include <mjs_reqer.h>
#include <mjs_on_action.h>
#include <mjs_mysql.h>
#include <mjs_server.h>
#include <mjs_client_proxy.h>

static const int8* DUYE_LOG_PREFIX = "mangjings.clientproxy";

MJSClientProxy::MJSClientProxy(const int32 sockfd, const std::string& ip, MJSOnActionMap* on_action_map, MJServer* mjserver) 
	: MJSClient(sockfd, ip, on_action_map, mjserver, MJSClient::CLIENT_MJC) {

	// init heartbeat timer
	if (duye::CfgMgr::ins().getValue("node:global.param:heartbeat", m_expire, "value")) {
		duye::TimerServer::instance().registerTimer(this, m_expire * 1000);
	} else {
		DUYE_ERROR("get node:global.param:heartbeat faield");
	}
}

MJSClientProxy::~MJSClientProxy() {
}

bool MJSClientProxy::handleAction(const std::list<MJMsgAction>& action_list) {
	if (authStatus() != AUTH_OK) {
		const MJMsgAction& action = action_list.front();
		if (action.getName() != "auth") {
			DUYE_WARN("client:%s don't auth, can't handle others action", m_ip.c_str());
			return false;
		}
	}

	std::list<MJMsgAction>::const_iterator iter = action_list.begin();
	for (; iter != action_list.end(); ++iter) {
		const MJMsgAction& action = *iter;
		MJSOnActionMap::iterator act_iter = m_on_action_map->find(action.getName());
		if (act_iter == m_on_action_map->end()) {
			DUYE_ERROR("have no action:%s in m_on_action_map", action.getName().c_str());
			continue;
		}

		act_iter->second->onAction((MJMsgAction*)&action, m_reqer);
	}

	return true;
}

bool MJSClientProxy::onTimeout(const uint32 timeout) {
	DUYE_WARN("client %s heartbeat timeout(%dms), will disconnect", m_ip.c_str(), timeout);
	m_mjserver->removeClient(m_sockfd);
	return true;
}

bool MJSClientProxy::innerNotify(const MJSInnerMsgType& msg_type, void* data) {
	switch (msg_type) {
		case MJS_INNER_UPCONNECT:
			upateTimeout();
			break;		
		default:
			DUYE_ERROR("unknown inner message type : %d", msg_type);
			return false;
			break;
	}

	return true;
}

void MJSClientProxy::upateTimeout() {
	if (!duye::TimerServer::instance().updateTimer(this, m_expire * 1000)) {
		DUYE_ERROR("%s update timeout failed", m_ip.c_str());
	} else {
		DUYE_DEBUG("%s update timeout(%ds) ok", m_ip.c_str(), m_expire);
	}
}